package com.hundsun.cprs.yyt.service.match.core.queue;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;

import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;

import com.hundsun.cprs.yyt.service.match.core.Matching;
import com.hundsun.cprs.yyt.service.match.domain.TradeEntrust;

/**
 * 订单队列，根据下单时间的升序(时间先优先)
 * 
 * @author fish
 * 
 */
public class EntrustQueue {

    private Set<TradeEntrust> entrusts = new TreeSet<TradeEntrust>(EntrustCellComparator);

    /**
     * EntrustCell的比较器
     */
    private static final Comparator<TradeEntrust> EntrustCellComparator = new Comparator<TradeEntrust>() {
        public int compare(TradeEntrust o1, TradeEntrust o2) {
            if (o1 == o2) {
                return 0;
            }
            long t1 = o1.getEntrustTime().getTime();
            long t2 = o2.getEntrustTime().getTime();
            if (t1 < t2) {
                return -1;
            }
            if (t1 > t2) {
                return 1;
            }
            // 竟然有相同时间的下单，那就比谁份额多
            t1 = o1.getEntrustAmount();
            t2 = o2.getEntrustAmount();
            if (t1 > t2) {
                return -1;
            }
            if (t1 < t2) {
                return 1;
            }
            // 晕倒，份额也相同，那就只有...
            // 根据主键的唯一字段区分
            return o1.getId().compareTo(o2.getId());
        }
    };

    private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();

    private ReadLock readLock = lock.readLock();

    private WriteLock writeLock = lock.writeLock();

    /**
     * 订单队列是否为空
     * 
     * @return
     */
    public boolean isEntrustEmpty() {
        return getEntrustSum() == 0;
    }

    public int getEntrustSum() {
        readLock.lock();
        try {
            return entrusts.size();
        } finally {
            readLock.unlock();
        }
    }

    public void addEntrust(TradeEntrust entrust) {
        writeLock.lock();
        try {
            this.entrusts.add(entrust);
        } finally {
            writeLock.unlock();
        }
    }

    /**
     * 得到队列的最早订单
     * 
     * @return
     */
    public TradeEntrust getHeader() {
        if (isEntrustEmpty()) {
            return null;
        }
        readLock.lock();
        try {
            return this.entrusts.iterator().next();
        } finally {
            readLock.unlock();
        }
    }

    @Override
    public String toString() {
        return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE).append("entrusts", entrusts).toString();
    }

    /**
     * 删除订单
     * 
     * @param entrust
     * @return
     */
    public boolean removeEntrust(TradeEntrust entrust) {
        writeLock.lock();
        try {
            return this.entrusts.remove(entrust);
        } finally {
            writeLock.unlock();
        }
    }

    /**
     * 所有订单剩余的份额总数
     * 
     * @return
     */
    public long getSurplusEntrustAmount() {
        long back = 0;
        readLock.lock();
        try {
            for (TradeEntrust cell : this.entrusts) {
                back += cell.getSurplusEntrustAmount();
            }
            return back;
        } finally {
            readLock.unlock();
        }
    }

    /**
     * 得到最前面的n个订单
     * 
     * @param n
     * @return
     */
    public List<TradeEntrust> findHeadEntrusts(int n) {
        List<TradeEntrust> back = new ArrayList<TradeEntrust>(n);
        if (this.entrusts != null && !this.entrusts.isEmpty()) {
            int i = 0;
            readLock.lock();
            try {
                Iterator<TradeEntrust> it = this.entrusts.iterator();
                while (i++ < n && it.hasNext()) {
                    back.add(it.next());
                }
            } finally {
                readLock.unlock();
            }
        }
        return back;
    }

    /**
     * 根据订单id查找订单
     * 
     * @param id
     * @return
     */
    public TradeEntrust findEntrustById(Long id) {
        readLock.lock();
        try {
            if (this.entrusts != null && !this.entrusts.isEmpty()) {
                Iterator<TradeEntrust> it = this.entrusts.iterator();
                while (it.hasNext()) {
                    TradeEntrust en = it.next();
                    if (en.getId().equals(id)) {
                        return en;
                    }
                }
            }
            return null;
        } finally {
            readLock.unlock();
        }
    }

    /**
     * 根据订单委托号查找订单
     * 
     * @param id
     * @return
     */
    public TradeEntrust findEntrustByEntrustNo(Long entrustNo) {
        readLock.lock();
        try {
            if (this.entrusts != null && !this.entrusts.isEmpty()) {
                Iterator<TradeEntrust> it = this.entrusts.iterator();
                while (it.hasNext()) {
                    TradeEntrust en = it.next();
                    if (en.getEntrustNO().equals(entrustNo)) {
                        return en;
                    }
                }
            }
            return null;
        } finally {
            readLock.unlock();
        }
    }

    public List<TradeEntrust> findAllEntrust() {
        readLock.lock();
        try {
            if (this.entrusts != null && !this.entrusts.isEmpty()) {
                return new ArrayList<TradeEntrust>(this.entrusts);
            }
            return null;
        } finally {
            readLock.unlock();
        }
    }
}
